import { Group, Vector3 } from '../libs/three137/three.module.js';
import { GLTFLoader } from '../libs/three137/GLTFLoader.js';
import { urls } from '../assets/store.js';
import { Explosion } from './Explosion.js';
const { PI , sin , cos , random, abs} = Math;
class Obstacles{
    constructor(game){
        this.assetsPath = game.assetsPath;
        this.loadingBar = game.loadingBar;
		this.game = game;
		this.scene = game.scene;
        this.loadStar();
		this.loadBomb();
		this.tmpPos = new Vector3();
		this.ready = false;
		this.explosions = new Set()
    }

    loadStar(){
    	const loader = new GLTFLoader( );
        
		// Load a glTF resource
		loader.load(
			// resource URL
			urls.star_blb,
			// called when the resource is loaded
			gltf => {

                this.star = gltf.scene.children[0];

                this.star.name = 'star';

				if (this.bomb !== undefined) this.initialize();

			},
			// called while loading is progressing
			xhr => {

                this.loadingBar.update('star', xhr.loaded, xhr.total );
			
			},
			// called when loading has errors
			err => {

				console.error( err );

			}
		);
	}	

    loadBomb(){
    	const loader = new GLTFLoader( );
        
		// Load a glTF resource
		loader.load(
			// resource URL
			urls.bomb_glb,
			// called when the resource is loaded
			gltf => {

                this.bomb = gltf.scene.children[0];

                if (this.star !== undefined) this.initialize();

			},
			// called while loading is progressing
			xhr => {

				this.loadingBar.update('bomb', xhr.loaded, xhr.total );
				
			},
			// called when loading has errors
			err => {

				console.error( err );

			}
		);
	}
	// 添加障碍物
	initialize(){
		console.log('obstacle init');
		this.obstacles =[] ;
        let g1 = new Group() ;
		g1.add(this.star) 
		this.bomb.rotation.x = PI* .5 ;
		let rotate =true;
		for( let y =5; y > -8; y-=2.5){ 
			rotate =!rotate ;
			if(!y) continue;
			let b  = this.bomb.clone() ;
			b.rotation.x= rotate? -PI* .5:0 ;
			b.position.y = y ;
			g1.add(b)

		};
		this.obstacles.push(g1) ;
		this.scene.add(g1) ;
		//克隆这一组
		for(let i= 0;i<3; i++	){
			let o = g1.clone() ;
			this.obstacles.push(o) ;
			this.scene.add(o)  ;
		}
		// 摆放
		this.reset() ;
		console.log(this.obstacles);
		this.ready =true ;
    }
	removeExplosion(explosion){ 
		if(this.explosions.has(explosion))this.explosions.delete(explosion)
		
	  }

    reset(){       
		this.obstacleSpawn = {pos:20, offset:5} ;
        this.obstacles.forEach((o)=> this.respawnObstacle(o)) ;

    }
	//重设一组障碍物，
    respawnObstacle( obstacle ){
        this.obstacleSpawn.pos += 30 ;
		let offset = (random()* 2 -1) * this.obstacleSpawn.offset ;
        this.obstacleSpawn.offset +=.2 ;
		obstacle.position.set(0, offset, this.obstacleSpawn.pos) ;
		obstacle.children[0].rotation.y = random()* PI *2 ;
		// 重置碰撞状态
		obstacle.userData.hit = false ;
		obstacle.children.forEach((child)=> { child.visible = true})
		let n =0;
		while(this.explosions.size && n < 300){ 
			n++
			[...this.explosions][0].onComplete();
		}
    }

	update(pos, time){
		let collisionObstacle, delInd =-1 ;// 可能碰到的 障碍物组 collision n 碰撞
		this.obstacles.forEach((obstacle, ind)=> { 
			const dZ = obstacle.position.z - pos.z ;
			if(abs(dZ) < 2 && !obstacle.userData.hit){
				// console.log(dZ);
				collisionObstacle = obstacle;
			 }
			 // 添加新的障碍物，无限障碍， 是不是应该吧这个给删掉 ,不用这个逻辑就是把消失的物体设置到了前方
			 if(dZ < -20){ 
				this.respawnObstacle(obstacle);
				delInd = ind ;
			 }
		});
		if(collisionObstacle){ 
			// console.log(collisionObstacle);
			collisionObstacle.children.some((child)=> {
				child.getWorldPosition(this.tmpPos) ;
				let d = this.tmpPos.distanceToSquared(pos)// 距离的平方
				if(d < 5){ 
					collisionObstacle.userData.hit =true ;
					this.hit(child);// 
					return true 
				}
			})
		}
		[...this.explosions].forEach((e)=> { e.update(time) })
		/*
		if(delInd > -1){ 
			this.obstacles[delInd] = null;// 没有dispose
			this.obstacles.splice(delInd, 1)
		}*/
        
    }

	hit(obj){
		if(obj.name=== 'star'){
			 this.game.inScore()
			 obj.visible = false ;
		}
		else { 
			this.game.decLives()
			// 撞到了就添加一个爆炸示例
			this.explosions.add(new Explosion(obj, this, )) // 把爆炸添加到目标物体，这样目标物体就不能直接消失了
		} 
	}
}

export { Obstacles };